package program;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;

import kernel.ProcessMemory;
import kernel.exception.OSException;
import kernel.process.AbstractProcess;
import kernel.process.AbstractProcessHeader;

/**
 * Man/Help process.
 * For more see man() method.
 * @author Veronika Vencurikova
 *
 */
public class Man extends AbstractProcess {
	
	public static final String NO_MAN = "This command doesn't have a man page.\n";
	public static final String NO_CMD = "This command doesn't exist.\n";

	public Man(AbstractProcessHeader header, long pid) {
		super(header, pid);
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String doJob(String input) throws OSException {
		if (this.params.size() > 1) throw new OSException(OSException.ERR_MANY_ARGS);

		StringBuffer sb = new StringBuffer();
		String pc = "";
		
		if (this.params.size() == 0) {
			sb.append("List of available commands:\n");
			
			for (String [] commands : ProcessMemory.getCommands()){
				sb.append(commands[0]+"\n");
			}
			
			return sb.toString();
		}
		
		for (String[] p: ProcessMemory.getCommands()) {
			if (p[0].equals(this.params.get(0))) {
				pc = p[1];
				break;
			}
		}
		if (!pc.equals("")) {
			sb.append("Man page for " + this.params.get(0).toUpperCase() + ":\n");
			try {
				AbstractProcessHeader abh = new AbstractProcessHeader(this.params.get(0), new ArrayList<String>(), "", "", false, this.shellID, this.userID);
				Class<?> c = Class.forName(pc);
				Class<?>[] argTypes = {AbstractProcessHeader.class, long.class};
				Constructor<?> constructor = c.getDeclaredConstructor(argTypes);
				Object[] arguments = {abh, 0};
				Object instance = constructor.newInstance(arguments);
				Method m = c.getMethod("man", new Class[]{String.class});
				sb.append((String) m.invoke(instance, this.params.get(0)));
			} catch (ClassNotFoundException e) {
				sb.append("Command does not exist.\n");
			} catch (NoSuchMethodException e) {
				e.printStackTrace();
			} catch (SecurityException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (InvocationTargetException e) {
				e.printStackTrace();
			} catch (InstantiationException e) {
				e.printStackTrace();
			}
		} else  {
			throw new OSException(NO_CMD);
		}
		
		return sb.toString();

	
	
	
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean needParams() {
		return false;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public void kill() throws OSException {
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public String continueJob() throws OSException {
		this.shouldEnd = true;
		return null;
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	protected String finalizeJob() throws OSException {
		return null;
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	public String man(String command) {
	String man = "";
			
			man += "    displays manual for command\n";
			man += "\n";
			man += "Command syntax:\n";
			man += "    "+command+" [COMMAND]\n";
			man += "\n";
			man += "Examples:\n";
			man += "    "+command+" cat\n";
			
			return man;
	}
}
